package com.yangyang.autobackup;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.example.FileInfo;
import org.example.LsOutputParser;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.util.*;

public class AutoBackup {
    private List<FileInfo> allBackupList = new LinkedList<>();
    private List<FileInfo> addList = new LinkedList<>();

    private String configLocalPath;
    private Set<String> exclusionsSet;
    private String dbPath;

    public AutoBackup() {
    }

    // 递归处理每个目录
    public void processDirectory(String path, String localPath) throws Exception {
        // 获取当前目录下的文件列表
        List<FileInfo> files = getFilesInDirectory(path);
        for (FileInfo file : files) {
            String remotePath = path + "/" + file.getFileName();

            if (exclusionsSet.contains(remotePath)) {
                continue;
            }

            String lPath = localPath + "/" + file.getFileName();
            if (file.isDirectory()) {
                // 如果是目录，递归处理子目录
                System.out.println("Entering directory: " + file.getFileName());
                processDirectory(remotePath, lPath);
            } else {
                // 如果是文件，拉取文件
                System.out.println("Pulling file: " + file.getFileName());

                file.setRemotePath(remotePath);
                file.setLocalPath(lPath);

                allBackupList.add(file);
                //pullFile(remotePath, lPath);
            }
        }
    }

    // 模拟执行 adb pull 命令
    private static void pullFile(String remotePath, String localPath) throws IOException {
        // 拼接 adb pull 命令
        String command = "adb pull \"" + remotePath + "\" \"" + localPath + "\"";
        System.out.println("Executing: " + command);
        // 执行命令
        Process process = Runtime.getRuntime().exec(command);
        try {
            process.waitFor(); // 等待命令执行完成
        } catch (InterruptedException e) {
            System.err.println(command);
            e.printStackTrace();
        }
    }

    // 从远程目录获取文件列表
    private static List<FileInfo> getFilesInDirectory(String path) throws Exception {
        // 运行 adb shell ls -lh 命令获取目录下的文件
        String command = "adb shell ls -lh " + path;
        Process process = Runtime.getRuntime().exec(command);

        // 获取命令输出
        List<String> outputLines = new ArrayList<>();
        try (BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                outputLines.add(line);
            }
        }

        // 解析命令输出
        return LsOutputParser.parseLsOutput(outputLines);
    }


//    static final String localPath = "C:/Users/yangyang/Desktop/auto-backup";

    private static final String USER_DIR = System.getProperty("user.dir");


    public void run() throws Exception {
        //List<FileInfo> allBackupList = new LinkedList<>();
        //List<FileInfo> addList = new LinkedList<>();

        File configFile = FileUtils.getFile(USER_DIR, "config", "config.json");
        if (!configFile.exists()) {
            throw new Exception("配置文件不存在：" + configFile.getAbsolutePath());
        }
        String configToString = FileUtils.readFileToString(configFile, "UTF-8");
        JSONObject configObject = JSONObject.parseObject(configToString);
        configLocalPath = configObject.getString("localPath");
        JSONArray remotePathArray = configObject.getJSONArray("remotePath");
        List<String> remotePathList = remotePathArray.toJavaList(String.class);
        JSONArray exclusionsArray = configObject.getJSONArray("exclusions");
        exclusionsSet = new HashSet<>(exclusionsArray.toJavaList(String.class));

        dbPath = FileUtils.getFile(configLocalPath, "auto_backup.db3").getAbsolutePath();

        DbUtil dbUtil = new DbUtil(dbPath);
        dbUtil.createDbFile();

        for (String remotePathname : remotePathList) {
            String baseName = FilenameUtils.getBaseName(remotePathname);
            String backPath = configLocalPath + "/" + baseName;
            // 从某个路径开始处理
            processDirectory(remotePathname, backPath);
        }

        // 从某个路径开始处理
        //processDirectory("/storage/emulated/0/DCIM", configLocalPath);


        Set<String> setNames = dbUtil.getAllOKSetNames();


        for (FileInfo info : allBackupList) {
            if (setNames.contains(info.getRemotePath())) continue;
            addList.add(info);
        }

        int insertFile = dbUtil.insertFile(addList);
        System.out.println("本次新增:" + insertFile);

        List<FileInfo> allAddFiles = dbUtil.getAllAddFiles();
        System.out.println(allAddFiles.size());
        for (FileInfo addFile : allAddFiles) {
            pullFile(addFile.getRemotePath(), addFile.getLocalPath());
            dbUtil.updateBakUpState(addFile.getId());
        }

    }

    public static void main(String[] args) {
        try {
            AutoBackup autoBackup = new AutoBackup();
            autoBackup.run();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}
